/**
 * @file    main.c
 * @brief   主函数
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-04-24
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * @par 项目配置:
 * <table>
 * <tr><th>项目平台    <th>家储平台项目V2
 * <tr><td>MCU型号     <td>M483KGCAE
 * </table>       
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-04-24 <td>1.0.1     <td>name     <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdint.h>
#include "FreeRTOS.h"
#include "task.h"
#include "drv_layer.h"
#include "If_do.h"
#include "app_disp.h"
#include "app_monitor.h"
#include "app_com_comm.h"
#include "If_com.h"
#include "If_rtc.h"
#include "app_nvm_mng.h"
#include "event_mng.h"
#include "param_mng.h"
#include "app_sample.h"
#include "soc_calc.h"
#include "app_can_comm.h"
#include "app_sox.h"
#include "app_diagnosis.h"
#include "app_pow_mng.h"
#include "If_nvm.h"
/* macro/define --------------------------------------------------------------*/
/* Priorities for the demo application tasks. 值越大优先级越高 */
/** @brief main check task */
#define mainCHECK_TASK_PRIORITY             ( tskIDLE_PRIORITY + 20UL )
#define mainCHECK_TASK_STACK_SIZE           ( configMINIMAL_STACK_SIZE )
#define mainCHECK_DELAY                     (( portTickType ) 5000 / portTICK_RATE_MS )
#define CREATE_TASK_STACK_SIZE              ( 128 )
#define CREATE_TASK_PRIORITY                ( tskIDLE_PRIORITY + 1UL )
/** @brief 用户监控任务配置 */
#define APP_MONITOR_TASK_PRIORITY           ( tskIDLE_PRIORITY + 3UL )
#define APP_MONITOR_TASK_STACK_SIZE         ( 64 )
/** @brief 创建COM通信任务 */
#define APP_COM_COMM_TASK_PRIORITY          ( tskIDLE_PRIORITY + 10UL ) 
#define APP_COM_COMM_TASK_STACK_SIZE        ( 1512 )
/** @brief 显示任务配置 */
#define APP_DISP_TASK_PRIORITY              ( tskIDLE_PRIORITY + 5UL )
#define APP_DISP_TASK_STACK_SIZE            ( 128 )
/** @brief 数据采样 */
#define APP_SAMPLE_TASK_PRIORITY            ( tskIDLE_PRIORITY + 8UL )
#define APP_SAMPLE_TASK_STACK_SIZE          ( 512 + 128 )
/** @brief 故障诊断 */
#define APP_DIAGNOSIS_TASK_PRIORITY         ( tskIDLE_PRIORITY + 9UL )
#define APP_DIAGNOSIS_TASK_STACK_SIZE       ( 384 )
/** @brief 事件记录 */
#define APP_NVM_MNG_TASK_PRIORITY           ( tskIDLE_PRIORITY + 6UL )
#define APP_NVM_MNG_TASK_STACK_SIZE         ( 256 )
/** @brief SOX */
#define APP_CALC_SOX_TASK_PRIORITY          ( tskIDLE_PRIORITY + 7UL )
#define APP_CALC_SOX_TASK_STACK_SIZE        ( 256 )
/** @biref CAN通信任务 */
#define APP_CAN_COMM_TASK_PRIORITY          ( tskIDLE_PRIORITY + 9UL )
#define APP_CAN_COMM_TASK_STACK_SIZE        ( 512 )
/** @biref 电源管理任务 */
#define APP_POW_MNG_TASK_PRIORITY           ( tskIDLE_PRIORITY + 4UL )
#define APP_POW_MNG_TASK_STACK_SIZE         ( 512 )
	
/* typedef -------------------------------------------------------------------*/

/* local functions -----------------------------------------------------------*/
static void vCheckTask( void *pvParameters );
static void vCreateTask(void *pvParameters );
/* static variables ----------------------------------------------------------*/
static rtc_data_type rtc_init_time = {
	.sec = 0,
	.min = 0,
	.hour = 18,
	.day = 25,
	.month = 4,
	.year = 2023 ,
};

/* global variables ----------------------------------------------------------*/
TaskHandle_t CreateTask_Handler;
TaskHandle_t DispLEDTask_Handler;
TaskHandle_t NvmTask_Handler;
TaskHandle_t SampleTaskHandler;
TaskHandle_t ComCommTaskHandler;
TaskHandle_t CanCommTaskHandler;
TaskHandle_t MonitorTaskHandler;
TaskHandle_t DiagTaskHandler;
TaskHandle_t SoxTaskHandler;
TaskHandle_t LmpTaskHandler;
/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */

/** ------------------------------------------------------------------------- *
  *                             Local function
 ** ------------------------------------------------------------------------- */

/**
 * @brief  主函数
 * @return int 
 */
int main(void)
{
    __enable_irq();
    /* Configure the hardware ready to run the test. */
    drv_layer_init();
	
    xTaskCreate( vCheckTask, "Check", mainCHECK_TASK_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
	
	xTaskCreate( vCreateTask, "Create_task", CREATE_TASK_STACK_SIZE, NULL, CREATE_TASK_PRIORITY, CreateTask_Handler );

    /* Start the scheduler. */
    vTaskStartScheduler();

    for( ;; );
}

/**
 * @brief 内存分配失败钩子函数
 */
void vApplicationMallocFailedHook( void )
{
    /* vApplicationMallocFailedHook() will only be called if
    configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
    function that will get called if a call to pvPortMalloc() fails.
    pvPortMalloc() is called internally by the kernel whenever a task, queue,
    timer or semaphore is created.  It is also called by various parts of the
    demo application.  If heap_1.c or heap_2.c are used, then the size of the
    heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
    FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
    to query the size of free heap space that remains (although it does not
    provide information on how the remaining heap might be fragmented). */
    taskDISABLE_INTERRUPTS();
    for( ;; );
}

/**
 * @brief 空闲任务钩子函数
 */
void vApplicationIdleHook( void )
{
    /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
    to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle
    task.  It is essential that code added to this hook function never attempts
    to block in any way (for example, call xQueueReceive() with a block time
    specified, or call vTaskDelay()).  If the application makes use of the
    vTaskDelete() API function (as this demo application does) then it is also
    important that vApplicationIdleHook() is permitted to return to its calling
    function, because it is the responsibility of the idle task to clean up
    memory allocated by the kernel to any task that has since been deleted. */
	xTaskGetTickCount();
}

/**
 * @brief  堆栈溢出钩子函数
 * @param  pxTask
 * @param  pcTaskName
 */
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
{
    ( void ) pcTaskName;
    ( void ) pxTask;

    /* Run time stack overflow checking is performed if
    configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
    function is called if a stack overflow is detected. */
    taskDISABLE_INTERRUPTS();
    for( ;; );
}

void vApplicationTickHook( void )
{
    /* This function will be called by each tick interrupt if
    configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h.  User code can be
    added here, but the tick hook is called from an interrupt context, so
    code must not attempt to block, and only the interrupt safe FreeRTOS API
    functions can be used (those that end in FromISR()).  */
	
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
    {
		
    }
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
}

/** ------------------------------------------------------------------------- *
  *                             Local function
 ** ------------------------------------------------------------------------- */
static void vCheckTask( void *pvParameters )
{
    portTickType xLastExecutionTime;

    xLastExecutionTime = xTaskGetTickCount();
	
    for( ;; )
    {
        /* Perform this check every mainCHECK_DELAY milliseconds. */
        vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
    }
}

static void vCreateTask(void *pvParameters )
{
	If_do_init_all();
	
	vTaskDelay(10);  /* 等待电源起来 */
	
	If_nvm_init();
	
	param_init();
    
    If_rtc_init(rtc_init_time);
    
	event_init();
   
	soc_calc_init();
	
	If_com_cfg_init();
    /** 显示任务 */
    xTaskCreate( vAppDispTasks, "App_Display", APP_DISP_TASK_STACK_SIZE, NULL, APP_DISP_TASK_PRIORITY, &DispLEDTask_Handler );
    /** 采样任务 */
	xTaskCreate( vAppSampleTask, "App_sample", APP_SAMPLE_TASK_STACK_SIZE, NULL, APP_SAMPLE_TASK_PRIORITY, &SampleTaskHandler );
    /** 监控任务 */
    xTaskCreate( vMonitorTask, "Monitor", APP_MONITOR_TASK_STACK_SIZE, NULL, APP_MONITOR_TASK_PRIORITY, &MonitorTaskHandler );
    /** 串口通信任务 */
    xTaskCreate( vComCommTask, "Com_Comm", APP_COM_COMM_TASK_STACK_SIZE, NULL, APP_COM_COMM_TASK_PRIORITY, &ComCommTaskHandler );
	/** CAN通信任务 */
	xTaskCreate( vCANCommTask, "CAN_Comm", APP_CAN_COMM_TASK_STACK_SIZE, NULL, APP_CAN_COMM_TASK_PRIORITY, &CanCommTaskHandler );
    /** 存储任务 */
    xTaskCreate( vNvmMngTasks, "Nvm_Mng", APP_NVM_MNG_TASK_STACK_SIZE, NULL, APP_NVM_MNG_TASK_PRIORITY, &NvmTask_Handler );
    /** 诊断任务 */
    xTaskCreate( vDiagnosisTask, "Diagnosis", APP_DIAGNOSIS_TASK_STACK_SIZE, NULL, APP_DIAGNOSIS_TASK_PRIORITY, &DiagTaskHandler );
    /** SOX任务 */
    xTaskCreate( vCalcSOXTask, "Calc_SOX", APP_CALC_SOX_TASK_STACK_SIZE, NULL, APP_CALC_SOX_TASK_PRIORITY, &SoxTaskHandler );
    /** 电源管理任务 */
    xTaskCreate( vPowMngTask, "Pow_mng", APP_POW_MNG_TASK_STACK_SIZE, NULL, APP_POW_MNG_TASK_PRIORITY, &LmpTaskHandler );
	
	vTaskDelete(NULL);
	
	for(;;)
	{
		
	}
}

/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
